package com.tree.backend.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Component
public class JwtUtil {
    // 从配置文件读取密钥，默认使用安全的随机密钥
    @Value("${jwt.secret:}")
    private String jwtSecret;

    // Token有效期（毫秒）- 从配置文件读取，默认24小时
    @Value("${jwt.expiration:86400000}")
    private long jwtExpiration;

    // 获取签名密钥
    private Key getSigningKey() {
        if (jwtSecret == null || jwtSecret.trim().isEmpty()) {
            // 如果配置的密钥为空，使用安全的随机密钥
            return Keys.secretKeyFor(SignatureAlgorithm.HS256);
        }
        return Keys.hmacShaKeyFor(jwtSecret.getBytes());
    }

    // 从Token中提取用户Id
    public String getUserIdFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }
    
    // 从Token中提取公司Id
    public Integer getCompanyIdFromToken(String token) {
        return getClaimFromToken(token, claims -> claims.get("companyId", Integer.class));
    }

    // 从Token中提取过期时间
    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }

    // 从Token中提取指定的声明
    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    // 解析Token获取所有声明
    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSigningKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    // 检查Token是否过期
    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    // 为指定用户生成Token
    public String generateToken(Integer userId, Integer companyId) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("companyId", companyId);
        return doGenerateToken(claims, userId);
    }

    // 生成Token的具体实现
    private String doGenerateToken(Map<String, Object> claims, Integer subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(String.valueOf(subject))
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration))
                .signWith(getSigningKey(), SignatureAlgorithm.HS256)
                .compact();
    }

    // 验证Token是否有效
    public Boolean validateToken(String token, Integer userId) {
        try {
            final String tokenUserId = getUserIdFromToken(token);
            return (tokenUserId.equals(String.valueOf(userId)) && !isTokenExpired(token));
        } catch (Exception e) {
            return false;
        }
    }
    
    // 验证Token是否有效（包含公司Id验证）
    public Boolean validateToken(String token, Integer userId, Integer companyId) {
        try {
            final String tokenUserId = getUserIdFromToken(token);
            final Integer tokenCompanyId = getCompanyIdFromToken(token);
            return (tokenUserId.equals(String.valueOf(userId)) && 
                    companyId.equals(tokenCompanyId) && 
                    !isTokenExpired(token));
        } catch (Exception e) {
            return false;
        }
    }
}